﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Reflection;
using System.Runtime.Serialization;
using System.Windows.Forms;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Xml.Serialization;
using OpenComposite.Workflow.Interfaces;
using System.Text.RegularExpressions;
using System.Collections;

namespace OpenComposite.Workflow
{
	#region Class: NotificationActivity : Activity
	[Designer(typeof(NotificationActivityDesigner))]
	[ToolboxItem(typeof(NotificationActivityToolBoxItem))]
	[ToolboxBitmap(typeof(resfinder), "OpenComposite.Workflow.Resources.email.png")]
	[ActivityValidator(typeof(NotificationActivityValidator))]
	public partial class NotificationActivity : Activity, ILogicalActivity, ITextActivity
	{
		public const string HostKey = "{0}_Host";
		public const string SenderKey = "{0}_Sender";
		public const string UserNameKey = "{0}_UserName";
		public const string PasswordKey = "{0}_Password";
		public const string RecipientKey = "{0}_Recipient";
		public const string SubjectKey = "{0}_Subject";
		public const string MessageKey = "{0}_Message";

		#region Initialization

		public NotificationActivity()
		{
			this.NotificationHost = "localhost";
			this.NotificationSender = "postmaster@localhost";

			base.SetReadOnlyPropertyValue(
				ParameterBindingsProperty, new WorkflowParameterBindingCollection(this));
		}

		#endregion

		#region Dependency Properties

		#region OLD CODE: BusinessObject
		//public static DependencyProperty BusinessObjectProperty = DependencyProperty.Register("BusinessObject", typeof(int), typeof(NotificationActivity));

		//[DescriptionAttribute("Business Object of the Activity")]
		//[CategoryAttribute("Notification")]
		//[BrowsableAttribute(false)]
		//[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		//public int BusinessObject
		//{
		//    get
		//    {
		//        return ( (int)( base.GetValue(NotificationActivity.BusinessObjectProperty) ) );
		//    }
		//    set
		//    {
		//        base.SetValue(NotificationActivity.BusinessObjectProperty, value);
		//    }
		//}
		#endregion

		#region Notification
		public static DependencyProperty NotificationProperty = DependencyProperty.Register("Notification", typeof(NotifcationData), typeof(NotificationActivity));

		[DescriptionAttribute("Input-Object of the Activity")]
		[CategoryAttribute("Notification")]
		[BrowsableAttribute(true)]
		[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		public NotifcationData Notification
		{
			get
			{
				return ( (NotifcationData)( base.GetValue(NotificationActivity.NotificationProperty) ) );
			}
			set
			{
				base.SetValue(NotificationActivity.NotificationProperty, value);
			}
		}
		#endregion

		#region SimulatedNotification
		public static DependencyProperty SimulatedNotificationProperty = DependencyProperty.Register("SimulatedNotification", typeof(NotifcationData), typeof(NotificationActivity));

		[DescriptionAttribute("Simulated NotificationData object")]
		[CategoryAttribute("Notification")]
		[BrowsableAttribute(false)]
		[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		public NotifcationData SimulatedNotification
		{
			get
			{
				return ( (NotifcationData)( base.GetValue(NotificationActivity.SimulatedNotificationProperty) ) );
			}
			set
			{
				base.SetValue(NotificationActivity.SimulatedNotificationProperty, value);
			}
		}
		#endregion

		#region NotificationHost
		public static DependencyProperty NotificationHostProperty = DependencyProperty.Register("NotificationHost", typeof(string), typeof(NotificationActivity));

		[DescriptionAttribute("NotificationHost")]
		[CategoryAttribute("Notification")]
		[BrowsableAttribute(true)]
		[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		public string NotificationHost
		{
			get
			{
				return ( (string)( base.GetValue(NotificationActivity.NotificationHostProperty) ) );
			}
			set
			{
				base.SetValue(NotificationActivity.NotificationHostProperty, value);
			}
		}
		#endregion

		#region NotificationSender
		public static DependencyProperty NotificationSenderProperty = DependencyProperty.Register("NotificationSender", typeof(string), typeof(NotificationActivity));

		[DescriptionAttribute("NotificationSender")]
		[CategoryAttribute("Notification")]
		[BrowsableAttribute(true)]
		[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		public string NotificationSender
		{
			get
			{
				return ( (string)( base.GetValue(NotificationActivity.NotificationSenderProperty) ) );
			}
			set
			{
				base.SetValue(NotificationActivity.NotificationSenderProperty, value);
			}
		}
		#endregion

		#region NotificationUserName
		public static DependencyProperty NotificationUserNameProperty = DependencyProperty.Register("NotificationUserName", typeof(string), typeof(NotificationActivity));

		[DescriptionAttribute("Notification User Name")]
		[CategoryAttribute("Notification")]
		[BrowsableAttribute(true)]
		[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		public string NotificationUserName
		{
			get
			{
				return ( (string)( base.GetValue(NotificationActivity.NotificationUserNameProperty) ) );
			}
			set
			{
				base.SetValue(NotificationActivity.NotificationUserNameProperty, value);
			}
		}
		#endregion

		#region NotificationPassword
		public static DependencyProperty NotificationPasswordProperty = DependencyProperty.Register("NotificationPassword", typeof(string), typeof(NotificationActivity));

		[DescriptionAttribute("Business Object of the Activity")]
		[CategoryAttribute("Notification")]
		[BrowsableAttribute(true)]
		[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
		[PasswordPropertyText(true)]
		public string NotificationPassword
		{
			get
			{
				return ( (string)( base.GetValue(NotificationActivity.NotificationPasswordProperty) ) );
			}
			set
			{
				base.SetValue(NotificationActivity.NotificationPasswordProperty, value);
			}
		}
		#endregion

		#region Text
		public static DependencyProperty TextProperty = DependencyProperty.Register(
			"Text", typeof(string), typeof(NotificationActivity), new PropertyMetadata(""));
		[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
		[DefaultValue("")]
		[Browsable(true)]
		public string Text
		{
			get
			{
				string text = (string)base.GetValue(NotificationActivity.TextProperty);
				if ( string.IsNullOrEmpty(text) ) return this.Name;
				return text;
			}
			set { base.SetValue(NotificationActivity.TextProperty, value); }
		}

		DependencyProperty ITextActivity.GetTextProperty()
		{
			return TextProperty;
		}
		#endregion

		#region ParameterBindings
		public static DependencyProperty ParameterBindingsProperty = DependencyProperty.Register(
			"ParameterBindings", typeof(WorkflowParameterBindingCollection), typeof(NotificationActivity),
			new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly,
				new Attribute[] { new BrowsableAttribute(false),
					new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content) }));

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public WorkflowParameterBindingCollection ParameterBindings
		{
			get
			{
				return base.GetValue(ParameterBindingsProperty) as WorkflowParameterBindingCollection;
			}
		}
		#endregion

		#endregion

		#region ILogicalActivity Members

		#region ActivitiesClass
		public static DependencyProperty ActivitiesClassProperty = DependencyProperty.Register(
			"ActivitiesClass", typeof(object), typeof(NotificationActivity), new PropertyMetadata(null));
		[Category("Notification")]
		[Browsable(false)]
		public object ActivitiesClass
		{
			get { return base.GetValue(NotificationActivity.ActivitiesClassProperty); }
			set { base.SetValue(NotificationActivity.ActivitiesClassProperty, value); }
		}
		#endregion

		#region LogicalActivityName
		public static DependencyProperty LogicalActivityNameProperty =
			DependencyProperty.Register("LogicalActivityName", typeof(string),
										typeof(NotificationActivity), new PropertyMetadata(null));
		[Browsable(false)]
		[Category("Notification")]
		public string LogicalActivityName
		{
			get { return (string)GetValue(LogicalActivityNameProperty); }
			set { SetValue(LogicalActivityNameProperty, value); }
		}

		#endregion

		#region LogicalActivityId
		public static DependencyProperty LogicalActivityIdProperty =
			DependencyProperty.Register("LogicalActivityId", typeof(int),
										typeof(NotificationActivity), new PropertyMetadata(null));
		[Browsable(false)]
		[Category("Notification")]
		public int LogicalActivityId
		{
			get { return (int)GetValue(LogicalActivityIdProperty); }
			set { SetValue(LogicalActivityIdProperty, value); }
		}
		#endregion

		#endregion

		#region Create & SendNotification

		#region Class: FileData

		[Serializable]
		private class FileData
		{
			private string _filename;
			public string Filename
			{
				get { return this._filename; }
				set { this._filename = value; }
			}

			private string _filetext;
			public string Filetext
			{
				get { return this._filetext; }
				set { this._filetext = value; }
			}
		}
		#endregion

		#region Private Methods

		private void fillKeywords(Type type)
		{
			fillKeywords(type, type.Name);
		}

		private void fillKeywords(Type type, string prefix)
		{
			try {
				PropertyInfo[] props = type.GetProperties();

				foreach ( PropertyInfo prop in props ) {
					if ( prop.PropertyType.IsArray ||
						 prop.PropertyType.BaseType.GetInterface("IEnumerable") != null ) {
						if ( prefix == null ) {
							_listNames.Add(prop.Name);
						} else {
							_listNames.Add(string.Format("{0}.{1}", prefix, prop.Name));
						}
					}
					if ( prop.DeclaringType != null && prop.PropertyType.FullName.StartsWith("System.") ) {
						if ( prefix == null ) {
							_propertyNames.Add(prop.Name);
						} else {
							_propertyNames.Add(string.Format("{0}.{1}", prefix, prop.Name));
						}
					} else {
						if ( prefix == null ) {
							fillKeywords(prop.PropertyType, prop.Name);
						} else {
							fillKeywords(prop.PropertyType, string.Format("{0}.{1}", prefix, prop.Name));
						}
					}
				}
			} catch ( Exception ex ) {
				Debug.WriteLine(
					ex.Source + " has encountered an error at " + ex.TargetSite + ":" +
					Environment.NewLine + Environment.NewLine +
					ex.Message, "Unhandled Exception");
			}
		}

		private object getNestedPropertyValue(object obj, List<string> hierarchy)
		{
			Type type = obj.GetType();
			if ( hierarchy.Count == 1 ) return type.GetProperty(hierarchy[0]).GetValue(obj, null);
			PropertyInfo pInfo = type.GetProperty(hierarchy[0]);
			hierarchy.RemoveAt(0);
			object returnValue = null;
			if ( hierarchy.Count > 0 ) {
				returnValue = getNestedPropertyValue(pInfo.GetValue(obj, null), hierarchy);
			}
			return returnValue;
		}

		private string createFile(FileData _input)
		{
			string subpath = "C:/";
			string filepath = subpath + _input.Filename;

			try {
				StreamWriter write = new StreamWriter(filepath);
				write.Write(_input.Filetext);
				write.Close();
			} catch ( Exception ex ) {
				Debug.WriteLine(
					ex.Source + " has encountered an error at " + ex.TargetSite + ":" +
					Environment.NewLine + Environment.NewLine +
					ex.Message, "Unhandled Exception");
			}

			return subpath + _input.Filename;
		}

		private string createNotification(bool send)
		{
			_propertyNames = new List<string>();
			_listNames = new List<string>();

			NotifcationData output = new NotifcationData();
			try {
				output.Type = this.Notification.Type;
				string recipient = ConfigurationManager.AppSettings[string.Format(RecipientKey, Name)];
				string subject = ConfigurationManager.AppSettings[string.Format(SubjectKey, Name)];
				string message = ConfigurationManager.AppSettings[string.Format(MessageKey, Name)];
				if ( recipient != null ) {
					output.Recipient = recipient;
					Debug.WriteLine(string.Format("[to]Config found. Using config values{0}{1}", Environment.NewLine, recipient));
				} else {
					output.Recipient = this.Notification.Recipient;
					Debug.WriteLine(string.Format("[to]No Config found. Using instance values{0}{1}", Environment.NewLine, this.Notification.Recipient));
				}
				if ( subject != null ) {
					output.Subject = subject;
					Debug.WriteLine(string.Format("[re]Config found. Using config values{0}{1}", Environment.NewLine, subject));
				} else {
					output.Subject = this.Notification.Subject;
					Debug.WriteLine(string.Format("[re]No Config found. Using instance values{0}{1}", Environment.NewLine, this.Notification.Subject));
				}
				if ( message != null ) {
					output.Message = message;
					Debug.WriteLine(string.Format("[msg]Config found. Using config values{0}{1}", Environment.NewLine, message));
				} else {
					output.Message = this.Notification.Message;
					Debug.WriteLine(string.Format("[msg]No Config found. Using instance values{0}{1}", Environment.NewLine, this.Notification.Message));
				}
			} catch ( Exception ex ) {
				Debug.WriteLine(
					ex.Source + " has encountered an error at " + ex.TargetSite + ":" +
					Environment.NewLine + Environment.NewLine +
					ex.Message, "Unhandled Exception");
			}

			string keyword = null;
			string value = null;
			string retval = "";
			try {
				foreach ( WorkflowParameterBinding wpb in this.ParameterBindings ) {
					try {
						object objInput = wpb.Value;
						if ( objInput == null ) continue;
						Debug.WriteLine("Current Input Object Type: " + objInput.GetType().FullName);
						fillKeywords(objInput.GetType(), wpb.ParameterName);
						foreach ( string property in _propertyNames ) {
							#region replace property values
							if ( !property.EndsWith(".ExtensionData") && property != "ExtensionData" ) {
								try {
									keyword = null;
									value = null;
									//Alle [/Keywords] mit den entsprechenden Werten in der .xml-Datei ersetzen
									List<string> hierarchy = new List<string>(property.Split('.'));
									if ( hierarchy.Count > 0 && hierarchy[0] == wpb.ParameterName ) {
										hierarchy.RemoveAt(0);
										object obj = getNestedPropertyValue(objInput, hierarchy);
										if ( obj == null ) value = "";
										value = obj.ToString();
										keyword = "[/" + property + "]";
										output.Recipient = output.Recipient.Replace(keyword, value);
										output.Subject = output.Subject.Replace(keyword, value);
										output.Message = output.Message.Replace(keyword, value);
									}
								} catch ( Exception ex ) {
									Debug.WriteLine("---------");
									Debug.WriteLine("Error while replacing keywords", "CreateNotification");
									Debug.WriteLine(ex.Message, "CreateNotification");
									Debug.WriteLine(string.Format("Property: {0}", property), "CreateNotification");
									if ( keyword != null ) {
										Debug.WriteLine(string.Format("Keyword: {0}", keyword), "CreateNotification");
									}
									if ( value != null ) {
										Debug.WriteLine(string.Format("Value: {0}", value), "CreateNotification");
									}
								}
							}
							#endregion
						}
						foreach ( var item in _listNames ) {
							#region generate list
							// set start and end tags
							string startTag = "[" + item + "]";
							string endTag = "[/" + item + "]";
							// find template string
							int posStart = output.Message.IndexOf(startTag);
							int posEnd = -1;
							// get array object
							IEnumerable objList = null;
							List<string> hierarchyArray = new List<string>(item.Split('.'));
							if ( hierarchyArray.Count > 0 && hierarchyArray[0] == wpb.ParameterName ) {
								hierarchyArray.RemoveAt(0);
								objList = getNestedPropertyValue(objInput, hierarchyArray) as IEnumerable;
							}
							// continue if not available
							if ( objList == null ) continue;
							// search for all
							while ( posStart != -1 ) {
								posEnd = output.Message.IndexOf(endTag, posStart);
								if ( posEnd == -1 ) break;
								// get template string
								string template = output.Message.Substring(
									posStart + startTag.Length,
									( posEnd - posStart ) - startTag.Length);
								// replace values of array items in template string
								// get required replacing items
								Regex regex = new Regex(@"\[\/([a-zA-Z0-9_.]*)\]");
								MatchCollection matches = regex.Matches(template);
								// for each item in the array object
								string result = "";
								foreach ( object obj in objList ) {
									string current = template;
									// foreach replacing item
									foreach ( Match match in matches ) {
										// get match value
										List<string> hierarchyMatch = new List<string>(
											match.Groups[1].Value.Replace(item + ".", "").Split('.'));
										hierarchyMatch.RemoveAt(0);
										object oMatch = getNestedPropertyValue(obj, hierarchyMatch);
										if ( oMatch != null ) {
											if ( oMatch is DateTime ) {
												// special handling for date time values
												DateTime dt = (DateTime)oMatch;
												string format = "g";
												if ( match.Value.ToLower().EndsWith("datetime]") ) {
													format = "f";
												} else if ( match.Value.ToLower().EndsWith("date]") ) {
													format = "D";
												} else if ( match.Value.ToLower().EndsWith("time]") ) {
													format = "t";
												}
												current = current.Replace(match.Value, dt.ToString(format));
											} else {
												// replace match with value
												current = current.Replace(match.Value, oMatch.ToString());
											}
										}
									}
									result += current;
								}
								// replace result into message
								output.Message = output.Message
									.Remove(posStart, posEnd + endTag.Length - posStart)
									.Insert(posStart, result);
								// set next start pos
								posStart = output.Message.IndexOf(startTag);
							}
							#endregion
						}
					} catch ( Exception ex ) {
						Debug.WriteLine(
							ex.Source + " has encountered an error at " + ex.TargetSite + ":" +
							Environment.NewLine + Environment.NewLine +
							ex.Message, "Unhandled Exception");
						throw new Exception("An exception occured while generating the notification", ex);
					}
				}
			} finally {
				SimulatedNotification = output;
			}
			try {
				if ( send ) {
					retval = sendNotification(output);
				}
			} catch ( Exception ex ) {
				Debug.WriteLine(
					ex.Source + " has encountered an error at " + ex.TargetSite + ":" +
					Environment.NewLine + Environment.NewLine +
					ex.Message, "Unhandled Exception");
				throw new Exception("An exception occured while sending the notification", ex);
			}
			return retval;
		}

		private string sendNotification(NotifcationData input)
		{
			string retval = "";

			switch ( input.Type ) {
				case SendType.Email:
					//Email-Object füllen für Übergabe an WebMethode
					try {
						try {
							// read smpt and sender settings from AppSettings
							string notifHost = ConfigurationManager.AppSettings[string.Format(HostKey, Name)];
							string notifSender = ConfigurationManager.AppSettings[string.Format(SenderKey, Name)];
							string notifUserName = ConfigurationManager.AppSettings[string.Format(UserNameKey, Name)];
							string notifPassword = ConfigurationManager.AppSettings[string.Format(PasswordKey, Name)];
							if ( notifHost != null ) {
								this.NotificationHost = notifHost;
								Debug.WriteLine(string.Format("[host]Config found. Using config values{0}{1}", Environment.NewLine, notifHost));
							} else {
								Debug.WriteLine(string.Format("[host]No Config found. Using instance values{0}{1}", Environment.NewLine, this.NotificationHost));
							}
							if ( notifSender != null ) {
								this.NotificationSender = notifSender;
								Debug.WriteLine(string.Format("[sender]Config found. Using config values{0}{1}", Environment.NewLine, notifSender));
							} else {
								Debug.WriteLine(string.Format("[sender]No Config found. Using instance values{0}{1}", Environment.NewLine, this.NotificationSender));
							}
							if ( notifUserName != null ) {
								this.NotificationUserName = notifUserName;
								Debug.WriteLine(string.Format("[user]Config found. Using config values{0}{1}", Environment.NewLine, notifUserName));
							} else {
								Debug.WriteLine(string.Format("[user]No Config found. Using instance values{0}{1}", Environment.NewLine, this.NotificationUserName));
							}
							if ( notifPassword != null ) {
								this.NotificationPassword = notifPassword;
								Debug.WriteLine(string.Format("[pass]Config found. Using config values{0}{1}", Environment.NewLine, notifPassword));
							} else {
								Debug.WriteLine(string.Format("[pass]No Config found. Using instance values{0}{1}", Environment.NewLine, this.NotificationPassword));
							}
						} catch { }
						MailMessage mail = null;
						try {
							mail = new MailMessage(this.NotificationSender,
								input.Recipient,
								input.Subject,
								input.Message);
						} catch {
							EventLog.WriteEntry("Notification Activity",
								string.Format("Notification not sent.{0}Sender:{1} {0}Recipient:{2} ({3})",
									Environment.NewLine, this.NotificationSender, input.Recipient,
									this.Notification.Recipient));
							throw;
						}
						SmtpClient smtpc = new SmtpClient(this.NotificationHost);
						if ( !string.IsNullOrEmpty(NotificationUserName) ) {
							smtpc.Credentials = new NetworkCredential(NotificationUserName, NotificationPassword);
						}
						smtpc.Send(mail);
						retval = "Email sent!";
					} catch ( Exception ex ) {
						retval = "Email not sent!";
						Debug.WriteLine(ex);
						throw;
					}
					retval += Environment.NewLine + Environment.NewLine +
						"To: " + input.Recipient + Environment.NewLine +
						"Subject: " + input.Subject + Environment.NewLine +
						"Body: " + input.Message;

					break;
				case SendType.Print:
					//Fülle-Object füllen für Übergabe an WebMethode
					_fileData.Filename = input.Recipient;
					_fileData.Filetext = input.Message;
					retval = createFile(_fileData);
					break;
				case SendType.SMS:
					retval = "Not implemented yet: SMS!";
					break;
				default:
					retval = "Error!" + Environment.NewLine + "Unknown MediaType!";
					break;
			}

			return retval;
		}

		#endregion

		#region Private Fields

		private FileData _fileData = new FileData();
		private List<string> _propertyNames;
		private List<string> _listNames;

		#endregion

		#endregion

		#region Execute
		protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
		{
			Activity wf = WorkflowHelpers.GetRootActivity(executionContext.Activity);
			Type t = wf.GetType();
			PropertyInfo isSim = t.GetProperty("IsSimulation");
			if ( isSim != null ) {
				bool isSimulation = (bool)isSim.GetValue(wf, null);
				if ( isSimulation ) {
					PropertyInfo isDocFlow = t.GetProperty("IsDocumentFlowSimulation");
					if ( isDocFlow != null ) {
						bool isDocumentFlowSimulation = (bool)isDocFlow.GetValue(wf, null);
						if ( isDocumentFlowSimulation ) {
							createNotification(false);
						}
					}
					return ActivityExecutionStatus.Closed;
				}
			}
			try {
				createNotification(true);
			} catch ( Exception ) {
				throw;
			}

			return ActivityExecutionStatus.Closed;
		}
		#endregion

	}

	#endregion

	#region Class: NotificationActivityDesigner : ExtendedActivityDesigner
	[ActivityDesignerTheme(typeof(NotificationActivityDesignerTheme))]
	public class NotificationActivityDesigner : ExtendedActivityDesigner
	{
		protected override void Initialize(Activity activity)
		{
			base.Initialize(activity);
		}

		internal NotificationActivity AssosicatedActivity
		{
			get { return this.Activity as NotificationActivity; }
		}

		protected override void OnDragEnter(ActivityDragEventArgs e)
		{
			base.OnDragEnter(e);
		}

		protected override void OnDragOver(ActivityDragEventArgs e)
		{
			//if ( e.Data.GetDataPresent(typeof(TreeNode)) ) {
			//    TreeNode tn = e.Data.GetData(typeof(TreeNode)) as TreeNode;
			//    if ( tn.Tag.GetType().FullName == "OpenComposite.EII.Repository.BusinessObject" ) {
			//        e.Effect = DragDropEffects.Link;
			//    }
			//}
			base.OnDragOver(e);
		}

		protected override void OnDragDrop(ActivityDragEventArgs e)
		{
			//if ( e.Data.GetDataPresent(typeof(TreeNode)) ) {
			//    TreeNode tn = e.Data.GetData(typeof(TreeNode)) as TreeNode;
			//    if ( tn.Tag.GetType().FullName == "OpenComposite.EII.Repository.BusinessObject" ) {
			//        Type t = tn.Tag.GetType();
			//        PropertyInfo pInfo = t.GetProperty("ID");
			//        this.AssosicatedActivity.BusinessObject = (int)pInfo.GetValue(tn.Tag, null);
			//    }
			//}
			base.OnDragDrop(e);
		}

	}

	[Serializable]
	public class NotificationActivityToolBoxItem : ActivityToolboxItem
	{
		public NotificationActivityToolBoxItem(Type type)
			: base(type)
		{
			base.DisplayName = "Notification";
		}

		private NotificationActivityToolBoxItem(SerializationInfo info, StreamingContext context)
		{
			Deserialize(info, context);
		}

	}

	public class NotificationActivityDesignerTheme : ActivityDesignerTheme
	{
		public NotificationActivityDesignerTheme(WorkflowTheme theme)
			: base(theme)
		{
			base.Initialize();
			this.BorderStyle = DashStyle.Solid;
			this.BorderColor = Color.FromArgb(193, 144, 29);
			this.BackColorStart = Color.Goldenrod;
			this.BackColorEnd = Color.Cornsilk;
			this.BackgroundStyle = LinearGradientMode.Horizontal;
			this.ForeColor = Color.Black;
		}
	}

	#endregion

	#region Class: NotifcationData
	[Serializable]
	public class NotifcationData
	{
		public NotifcationData()
		{
			_type = SendType.Email;
		}

		private SendType _type;
		public SendType Type
		{
			get { return _type; }
			set { _type = value; }
		}

		private string _Recipient;
		public string Recipient
		{
			get { return _Recipient; }
			set { _Recipient = value; }
		}

		private string _Subject;
		public string Subject
		{
			get { return _Subject; }
			set { _Subject = value; }
		}

		private string _Message;
		public string Message
		{
			get { return _Message; }
			set { _Message = value; }
		}
	}
	#endregion

	#region Enum: SendType
	public enum SendType
	{
		Email,
		Print,
		SMS
	}
	#endregion
}
